namespace RBAC.Read.Api.Application.Handler.ERP.OutboundManagement
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading;
    using System.Threading.Tasks;
    using MediatR;
    using Microsoft.Extensions.Logging;
    using RBAC.Domain.MaterialManage;
    using RBAC.Domain.SalesManage;
    using RBAC.ErrorCode;
    using RBAC.Interstructrue.Base;
    using RBAC.Read.Api.Application.Command.ERP.OutboundManagement;
    using RBAC.Read.Api.Application.Dto.ERP;

    /// <summary>
    /// 根据销售订单ID获取物料列表 处理器
    /// </summary>
    public class GetMaterListBySalesOrdeIdHandler : IRequestHandler<GetMaterListBySalesOrdeIdCommand, APIResult<List<MaterListDto>>>
    {
        private readonly IBaseRepository<SalesOrderDetail> detailRepo;
        private readonly IBaseRepository<Mater> materRepo;
        private readonly ILogger<GetMaterListBySalesOrdeIdHandler> logger;

        public GetMaterListBySalesOrdeIdHandler(
            IBaseRepository<SalesOrderDetail> detailRepo,
            IBaseRepository<Mater> materRepo,
            ILogger<GetMaterListBySalesOrdeIdHandler> logger)
        {
            this.detailRepo = detailRepo;
            this.materRepo = materRepo;
            this.logger = logger;
        }

        public Task<APIResult<List<MaterListDto>>> Handle(GetMaterListBySalesOrdeIdCommand request, CancellationToken cancellationToken)
        {
            var result = new APIResult<List<MaterListDto>>();
            try
            {
                logger.LogInformation("根据销售订单ID获取物料列表 SalesOrderId={SalesOrderId}", request.SalesOrderId);

                // 读取该订单的明细（排除逻辑删除），提取物料ID
                var details = detailRepo.GetAll("SalesOrderId = @SalesOrderId AND IsDeleted = 0", new { SalesOrderId = request.SalesOrderId })?.ToList() ?? new List<SalesOrderDetail>();

                if (details.Count == 0)
                {
                    result.Code = APIEnums.Success;
                    result.Msg = "无明细数据";
                    result.Data = new List<MaterListDto>();
                    return Task.FromResult(result);
                }

                var materIds = details.Select(d => d.MaterId).Distinct().ToList();

                // 汇总每个物料在该订单明细中的数量（对明细数量字段求和）
                var materCountDict = details
                    .GroupBy(d => d.MaterId)
                    .ToDictionary(g => g.Key, g => g.Sum(x => x.Num ?? 0));

                // 组装 IN 子句
                var inClause = string.Join(",", materIds.Select((_, idx) => $"@Id{idx}"));
                var parameters = materIds.Select((id, idx) => new { Key = $"@Id{idx}", Value = (object)id })
                                          .ToDictionary(x => x.Key, x => x.Value);

                var maters = materRepo.GetAll($"Id IN ({inClause})", parameters) ?? new List<Mater>();

                var list = maters.Select(m => new MaterListDto
                {
                    Id = m.Id,
                    MaterCode = m.MaterCode,
                    MaterName = m.MaterName,
                    ModelSpec = m.ModelSpec,
                    Unit = m.Unit,
                    SupplyMode = m.SupplyMode,
                    Status = m.Status,
                    Num = materCountDict.TryGetValue(m.Id, out var cnt) ? cnt : 0
                }).ToList();

                result.Code = APIEnums.Success;
                result.Msg = "获取成功";
                result.Data = list;
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "根据销售订单ID获取物料列表失败: {Message}", ex.Message);
                result.Code = APIEnums.Error;
                result.Msg = "获取失败";
                result.Data = new List<MaterListDto>();
            }

            return Task.FromResult(result);
        }
    }
}
